function getModel() {
    const model = tf.sequential();
    return model;
  }
  function initModel(model,inputShape, numClasses){
  const [height, width, numChannels] = inputShape;

  // 1. 计算每层的filter数量和卷积核大小
  const filters = Math.min(64, Math.floor(numChannels / 2));
  const kernelSize = Math.min(height, width, 5);

  // 2. 添加卷积层
  model.add(tf.layers.conv2d({
    filters,
    kernelSize,
    strides: 1,
    padding: 'same',
    activation: 'relu',
    inputShape,
  }));

  // 3. 添加最大池化层
  const poolSize = 2;
  model.add(tf.layers.maxPooling2d({ poolSize }));

  // 4. 计算全连接层大小
  const poolOutShape = model.layers[model.layers.length - 1].outputShape;
  const fcInputSize = poolOutShape[1] * poolOutShape[2] * poolOutShape[3];

  // 5. 添加全连接层
  model.add(tf.layers.flatten());
  model.add(tf.layers.dense({
    units: Math.max(numClasses, 32),
    activation: 'relu',
    inputShape: [fcInputSize],
  }));

  // 6. 添加输出层
  model.add(tf.layers.dense({
    units: numClasses,
    activation: 'softmax',
  }));

  // 打印模型信息
  model.summary();
model.compile({
	optimizer: 'adam', loss: 'categoricalCrossentropy', metrics: ['accuracy']
	});
  return model;

  }
const onBatchEnd = async (batch, logs) => {
  console.log(`Batch ${batch}: loss = ${logs.loss.toFixed(4)}`);
  getLoss(logs.loss.toFixed(4));
  
};
const onTrainEnd = async () => {
  getLoss("训练结束");
  pagecode(5)
};
  async function train(model) {
	  //训练神经网络
	// const trainData = tf.tensor(images).reshape([images.length, 160, 160, 3]);
	  trainLabels = tf.tensor(trainLabels, [trainLabels.length], 'int32');
	 trainLabelsOneHot = tf.oneHot(trainLabels, labelNum);
trainData=tf.stack(images);
await model.fit(trainData, trainLabelsOneHot, {batchSize: 32, epochs: 10,
 callbacks: {
onBatchEnd,
onTrainEnd},}).then((history) => {
});

  }
function doPrediction(model, data, testDataSize = 500) {
  const IMAGE_WIDTH = 28;
  const IMAGE_HEIGHT = 28;
  const testData = data.nextTestBatch(testDataSize);
  const testxs = testData.xs.reshape([testDataSize, IMAGE_WIDTH, IMAGE_HEIGHT, 1]);
  const labels = testData.labels.argMax(-1);
  const preds = model.predict(testxs).argMax(-1);

  testxs.dispose();
  return [preds, labels];
}




var labels={
}
var images=[];
var trainLabels=[];
var labelNum=0;
function ConfirmModuleName(Name){
	
	document.getElementById("info").innerHTML="模型已经创建:"+Name;
	document.getElementById("takeName").style="display:none";
}
 /* async function run() {
    const data = new MnistData();
    await data.load();
    await showExamples(data);

document.getElementById("takeName").style="display:flex";
Steps="TakeName";
   tfvis.show.modelSummary({name: 'Model Architecture', tab: 'Model'}, model);

    await train(model, data);
    await showAccuracy(model, data);
    await showConfusion(model, data);
  }*/
  
 // document.addEventListener('DOMContentLoaded', run);
new Vue({
  el: '#app',
  data: {
	pagecode:0,
    message: '',
	hLabels: '',
	loss:'暂时未收到loss',
  interval:"",
  camera:0,
  model:"",
  testResult:0
  },
  methods: {
  run: function(){
	  this.pagecode=1;
  },
  getName: function(){
	    userModule={
		name:moduleName.value
	  }
	   this.message="已经创建模型"+moduleName.value;
	   this.pagecode=2;
  },
  imgNet: function(){
	 // this.message="我们已经为您预先设置到网络结构，自定义网络结构正在开发中<br>";
	 // this.message+="网络结构如下:<br>输入维度：三维（宽+高+单通道灰度)<br>";
	//  this.message+="卷积层：2层<br>卷积核大小：5<br>滤波器：8<br>步长：1:<br>激活函数：relu<br>";
	 // this.message+="池化层两层<br>池化层参数：poolSize: [2, 2], strides: [2, 2]<br>最后是softmax的全连接层<br>训练批次10";
	  this.pagecode=3;
    this.camera=1;
  },
  start: async function(){
    this.camera=0;
	  this.model=getModel();
	  const inputShape = [160, 160, 3];
	  const numClasses = labelNum;

   initModel(this.model,inputShape, numClasses);
   const numParams = this.model.countParams();
   console.log(`Model parameters: ${numParams}`);
this.pagecode=4;
   await train(this.model);
   
  },
  addLabel: function(){
	  try{
	  if(label.value!=""&&!labels[label.value]){
	  labels[label.value]={
		  name:label.value,
		  num:0,
	  };
	  labelNum+=1;
	  this.hLabels="";
	  for(i in labels){
	  this.hLabels+="标签:"+ labels[i].name+" 数据量:"+labels[i].num+"<br>";
	  }
	  }else{
		  alert("参数有误");
	  }
	  }
	  catch(err){
	  }
  },
  capture: function(){
	  if(choosedLabel.value!=""){
    this.interval= setInterval(() => {
	  context.drawImage(video,0,0,160,160);
			
  var imageData = context.getImageData(0, 0, 160,160);
var imageTensor = tf.browser.fromPixels(imageData).div(255.0);
  imageTensor = imageTensor.reshape([160, 160, 3]);
    trainLabels.push(choosedLabel.value);
    images.push(imageTensor);
 
  labels[choosedLabel.value]["num"]+=1;
   this.hLabels="";
	  for(i in labels){
	  this.hLabels+="标签:"+ labels[i].name+" 数据量:"+labels[i].num+"<br>";
	  }
  }, 1000 / 60); 
	  }else{
		  alert("你至少要选一个标签呀")
	  }
  },
  stop: function(){
clearInterval(this.interval);
  },
  changeLoss: function(loss){
	  this.loss=loss;
  },
  test: function(){
    this.camera=1;
    context.drawImage(video,0,0,160,160);
    var imageData = context.getImageData(0, 0, 160,160);
  var imageTensor = tf.browser.fromPixels(imageData).div(255.0);
    imageTensor = imageTensor.reshape([1,160, 160, 3]);
    var prediction = this.model.predict(imageTensor).arraySync();
    this.testResult=prediction;

  }
  },
     mounted(){//vue生命周期。载入后执行

            window.getLoss = (loss)=>{
                this.changeLoss(loss);

            },
			window.pagecode = (code)=>{
				this.pagecode=code;
			}

        }
})